package cn.xiaolang.thread.threadlocal;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * Mock threadLocal 内存泄露示例
 *
 * @author Dean
 * @date 2021-01-18
 */
@Slf4j
public class ThreadLocalLeakSample {

    @Data
    @AllArgsConstructor
    private static class LocalVariable {

        private String name;

    }

    private static final ThreadPoolExecutor poolExecute = new ThreadPoolExecutor(
            5,
            5, 1,
            TimeUnit.MINUTES, new LinkedBlockingDeque<>(),
            new ThreadFactoryBuilder().setNameFormat("dean-%d").build());

    private static final ThreadLocal<LocalVariable> THREAD_LOCAL = new ThreadLocal<>();

    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < 50; i++) {
            final int index = i;
            poolExecute.execute(new Runnable() {
                @SneakyThrows
                @Override
                public void run() {
                    THREAD_LOCAL.set(new LocalVariable("HI-" + index));
                    TimeUnit.SECONDS.sleep(3);
                    log.info("get value:{}", THREAD_LOCAL.get());
                    THREAD_LOCAL.remove();
                }
            });
        }
    }


}

